package com.iscreen.utils.xml;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;

import com.iscreen.utils.exceptions.IScreenException;
import com.iscreen.utils.exceptions.IScreenExceptionCodes;

public final class JAXBUtils
{
	private static InputStream getXMLInputStream(String dataFileName) throws IScreenException
	{
		try
		{
			return new FileInputStream(dataFileName);
		}
		catch (FileNotFoundException e)
		{
			throw new IScreenException(IScreenExceptionCodes.XML_BINDING_ERROR, e);
		}
	}
	public static <T> T unmarshal(Class<T> docClass, String dataFileName,String schemaFileName) throws IScreenException
	{
		Schema schema = null;
		if (schemaFileName != null)
		{
			schema = XMLUtils.getSchema(schemaFileName);
		}
		InputStream inputStream = getXMLInputStream(dataFileName);
		return unmarshal(docClass, inputStream, schema);
	}

	public static <T> T unmarshal(Class<T> docClass, String dataFileName) throws IScreenException
	{
		return unmarshal(docClass, dataFileName, null);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T unmarshal(Class<T> docClass, InputStream inputStream, Schema schema) throws IScreenException
	{
		String packageName = docClass.getPackage().getName();
		try
		{
			JAXBContext jc = JAXBContext.newInstance(packageName);
			Unmarshaller u = jc.createUnmarshaller();
			if (schema != null)
			{
				u.setSchema(schema);
			}
			JAXBElement<T> doc = (JAXBElement<T>) u.unmarshal(inputStream);
			return doc.getValue();
		}
		catch (JAXBException e)
		{
			throw new IScreenException(IScreenExceptionCodes.XML_BINDING_ERROR, e);
		}
	}
}
